package Thread_.homework;

/**
 * 编写代码, 实现阻塞队列案例
 * 通过 循环数组的方式 实现
 * 完成构造方法,put,take
 */
class MyBlockingQueue{
    private String[] elem=null;
    private int head=0;
    private int tail=0;
    private int size=0;
    public MyBlockingQueue(int capacity){//设置队列容量
        elem=new String[capacity];
    }
    private Object locker=new Object();
    //插入元素
    public void put(String s) throws InterruptedException {
        //多线程下,防止对数组的修改 引发线程安全问题,要进行加锁
        synchronized(locker){
            while(elem.length == size){//队列已满
//                continue;
                locker.wait();//此时要 将锁释放,并进入 WAITING阻塞状态
            }
            elem[tail] = s;
            tail++;
            if(tail >= elem.length){
                tail = 0;//让队列 循环起来
            }
            size++;
            locker.notify();//put后,队列不为空,唤醒take时,因数组为空而阻塞的线程
        }
    }
    //取出队头元素
    public String take() throws InterruptedException {
        synchronized(locker){
            while(size == 0){
                locker.wait();
    //            continues;
            }
            String top=elem[head];
            head++;
            if(head>=elem.length){
                head=0;//让队列 循环起来
            }
            size--;
            //取出元素后,队列不为满,唤醒put时因队满,而阻塞的线程
            locker.notify();
            return top;
        }
    }
}
public class test15 {
    public static void main(String[] args) throws InterruptedException {
        MyBlockingQueue queue = new MyBlockingQueue(4);
        queue.put("hehe");
        queue.put("sisi");
        queue.put("hede");
        queue.put("cici");
//        queue.put("wici");
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
//        System.out.println("haha");

    }
}
